<?php

namespace app\base\command;


use app\base\model\RedianData;
use app\base\model\RedianTask;
use app\base\service\MemberService;
use app\base\service\TaskService;
use think\admin\Command;
use think\console\Input;
use think\console\Output;
/**
 * 自定义任务运行
 * Class SmsNum
 * @package app\common\command
 */
class TaskRun extends Command
{
    /**
     * 配置指令
     */
    protected function configure()
    {
        $this->setName('xbase:taskRun');
        $this->setDescription('TaskRun');
    }

    protected function execute(Input $input, Output $output)
    {
        $queue_data = $this->queue->data;
        $task_id = $queue_data['task_id'];
        $task_run_log_id = 0;
        if(isset($queue_data['task_run_log_id'])){
            $task_run_log_id = $queue_data['task_run_log_id'];
        }
        $this->setQueueProgress("开始执行任务", 0);
        $task = RedianTask::mQuery()->where([ "id"=>$task_id])->find();
        if(empty($task)){
           // $this->error('任务不存在');
            $this->setQueueError("任务不存在");
        }
        $progress = $task['progress'];
        if($task['type']==1){
            $this->checkBeans($task,1,$task_run_log_id);
            if($progress==0 || $progress==1){
                //开始采集任务
                $this->setQueueProgress("开始采集任务,请稍等...", 0);
                RedianTask::mQuery()->where([ "id"=>$task_id])->update(['progress'=>1]);
                $res = TaskService::instance()->startGatherCoze($task);
                if($res['code']==0){
                    RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"采集失败:".$res['msg'],'error_status'=>1,'status'=>1]);
                    if($task_run_log_id){
                        $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"采集失败"]);
                    }
                    $this->setQueueError("任务执行失败:采集失败");

                }else{
                    sleep(30);
                    $execute_id = $res['data'];
                    $i = 0;
                    while ( $i<$task['num']+1){
                        //采集状态查询
                        $this->setQueueProgress("查询采集结果,请稍等...".$execute_id, 0);
                        $res = TaskService::instance()->getWorkflowResult($task,$execute_id,$task_run_log_id);
                        $this->setQueueProgress("第{$i}次采集结果,".json_encode($res), 0);
                        if($res==0){
                            RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"查询采集结果失败:".$res['msg'],'error_status'=>1,'status'=>1]);
                            if($task_run_log_id){
                                $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"采集失败:查询采集结果失败"]);
                            }
                            $this->setQueueError("任务执行失败:查询采集结果失败");

                        }elseif ($res==1){
                            //采集成功
                            break;
                        }else{
                            sleep(60);
                        }
                        $i++;
                    }
                    $r = RedianData::mQuery()->where(['task_id'=>$task_id,"task_run_log_id"=>$task_run_log_id])->count();
                    if($r==0){
                        RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"采集失败:无采集结果",'error_status'=>1,'status'=>1]);
                        if($task_run_log_id){
                            $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"采集失败:无采集结果"]);
                        }
                        $this->setQueueError("任务执行失败:无采集结果");
                    }
                }
                $progress=2;
            }



            if($progress==2){
                $this->checkBeans($task,2,$task_run_log_id);
                //计算相似度
                $this->setQueueProgress("开始筛选文案,请稍等...", 20);
                RedianTask::mQuery()->where([ "id"=>$task_id])->update(['progress'=>2]);
                $redian_data = TaskService::instance()->similarity($task,$task_run_log_id);
                if(empty($redian_data)){
                    RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"相似度计算失败",'error_status'=>2,'status'=>1]);
                    if($task_run_log_id){
                        $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"相似度计算失败"]);
                    }
                    $this->setQueueError("任务执行失败:相似度计算失败");

                }
                $out_redian_data = RedianData::mQuery()->where(['task_id'=>$task_id,"task_run_log_id"=>$task_run_log_id])
                    ->where('similarity','>',0)->order('similarity desc')->limit(0,$task['out_num'])->select()->toArray();
                $out_redian_data_ids = array_column($out_redian_data,'id');
                RedianData::mQuery()->whereIn('id',$out_redian_data_ids)->update(['filter_status'=>1]);
                $progress=3;

            }

            if( $progress==3){
                $this->checkBeans($task,3,$task_run_log_id);
                //口播文本生成
                $this->setQueueProgress("开始口播文本生成,请稍等...", 40);
                RedianTask::mQuery()->where([ "id"=>$task_id])->update(['progress'=>3]);
                $f = true;
                $f_num = 0;
                while ($f){
                    $f = $this->textGenerate($task,$task_run_log_id);
                    $f_num++;
                    if($f_num>5){
                        $f = false;

                    }

                }
                $c = RedianData::mQuery()->where(['task_id'=>$task['id'],'gaixie_status'=>2,'task_run_log_id'=>$task_run_log_id])->count();
                if($c==0){
                    RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"AI改写失败",'error_status'=>3,'status'=>1]);
                    if($task_run_log_id){
                        $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"AI改写失败"]);
                    }
                    $this->setQueueError("任务执行失败:AI改写失败");
                }



                $progress=4;
            }

        }else{
            $progress=4;
        }


        if($progress==4){
            $this->checkBeans($task,4,$task_run_log_id);
            //音频生成
            $this->setQueueProgress("开始音频生成,请稍等...", 60);
            RedianTask::mQuery()->where([ "id"=>$task_id])->update(['progress'=>4]);
            $redian_data = TaskService::instance()->audioGenerate($task,$task_run_log_id);
            if(empty($redian_data)){
                RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"音频生成失败",'error_status'=>4,'status'=>1]);
                if($task_run_log_id){
                    $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"音频生成失败"]);
                }
                $this->setQueueError("任务执行失败:音频生成失败111");

            }
            //使用蝉镜生成音频,需等待蝉镜音频生成完成
            if($task['audio_platform']=="蝉镜"){
                $audio_result = false;
                while (!$audio_result){
                    $this->setQueueProgress("等待音频生成结果{$audio_result}");
                    sleep(60);
                    //还有正在生成中的音频生成任务继续等待
                    $mun = RedianData::mQuery()->where(["task_id"=>$task_id,"task_run_log_id"=>$task_run_log_id])->where(['audio_status'=>2])->count();
                    if($mun>0){
                        $this->setQueueProgress("有音频生成任务正在处理中...{$mun}");
                    }else{
                        $audio_result = true;
                        $this->setQueueProgress("音频生成完成");
                    }
                }
                sleep(10);
                $r = RedianData::mQuery()->where(["task_id"=>$task_id,"task_run_log_id"=>$task_run_log_id])->where(['audio_status'=>3])->count();
                $this->setQueueProgress("音频生成结果{$r}");
                if($r==0){
                    RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"音频生成失败",'error_status'=>4,'status'=>1]);
                    if($task_run_log_id){
                        $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"音频生成失败"]);
                    }
                    $this->setQueueError("任务执行失败:音频生成失败{$r}");
                }
            }

            $progress=5;
        }
        if($progress == 5){
            $this->checkBeans($task,5,$task_run_log_id);
            //视频生成
            $this->setQueueProgress("开始视频生成,请稍等...", 80);
            RedianTask::mQuery()->where([ "id"=>$task_id])->update(['progress'=>5]);
            $redian_data = TaskService::instance()->videoGenerate($task,$task_run_log_id);
            if(empty($redian_data)){
                RedianTask::mQuery()->where([ "id"=>$task_id])->update(['error_msg'=>"视频生成失败",'error_status'=>5,'status'=>1]);
                if($task_run_log_id){
                    $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"视频生成失败"]);
                }
                $this->setQueueError("任务执行失败:视频生成失败");
            }
            if($task['video_platform']=="HeyGen"){
                //创建视频生成状态查询任务
                sysqueue($task['title']."视频生成状态查询任务", "xbase:heygenRetrieve",  10, $data = [
                    'task_id'=>$task_id,'task_run_log_id'=>$task_run_log_id
                ], $rscript = 1, $loops = 0);
            }
            if($task['video_platform']=="小甲鱼"){
                // 创建视频生成状态查询任务
                sysqueue($task['title']."视频生成状态查询任务(小甲鱼)", "xbase:XiaojiayuRetrieve",  10, $data = [
                    'task_id'=>$task_id,'task_run_log_id'=>$task_run_log_id
                ], $rscript = 1, $loops = 0);
            }

        }





        $this->setQueueProgress("任务完成", 100);
        $this->setQueueSuccess("任务完成");


    }

    public function textGenerate($task,$task_run_log_id)
    {
        $redian_data = 0;
        //判断改写后的数量和产出数量是否相等
        if($redian_data<$task['out_num']){
            //如果数量不足
            $out_redian_data = RedianData::mQuery()->where(['task_id'=>$task['id'],"task_run_log_id"=>$task_run_log_id,'filter_status'=>0])
                ->where('similarity','>',0)->order('similarity desc')->limit(0,($task['out_num']-$redian_data))->select()->toArray();
            if(!empty($out_redian_data)){
                $out_redian_data_ids = array_column($out_redian_data,'id');
                RedianData::mQuery()->whereIn('id',$out_redian_data_ids)->update(['filter_status'=>1]);
                $redian_data = TaskService::instance()->textGenerate($task,$task_run_log_id);
                if($redian_data<$task['out_num']){
                    return true;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

    public function checkBeans($task,$progress,$task_run_log_id)
    {
        $beans = MemberService::instance()->getUserRemainingBeans($task['user_id']);
        if($beans<2){
            RedianTask::mQuery()->where([ "id"=>$task['id']])->update(['error_msg'=>"蓝豆不足",'error_status'=>$progress,'status'=>1]);
            if($task_run_log_id){
                $this->app->db->name("task_run_log")->where(["id"=>$task_run_log_id])->update(['result'=>"蓝豆不足"]);
            }
            $this->setQueueError("任务执行失败:蓝豆不足");
        }
    }




}
